<template>
  <div class="sales-goal-card">
    <div class="card-header">
      <h3 class="card-title">销售目标完成率</h3>
      <div class="period-selector">
        <el-radio-group v-model="selectedPeriod" @change="handlePeriodChange" size="small">
          <el-radio-button label="weekly">周</el-radio-button>
          <el-radio-button label="monthly">月</el-radio-button>
          <el-radio-button label="quarterly">季</el-radio-button>
          <el-radio-button label="yearly">年</el-radio-button>
        </el-radio-group>
      </div>
    </div>
    
    <div class="goal-content">
      <div class="goal-gauge">
        <div class="gauge-container" ref="gaugeRef"></div>
        <div class="gauge-center">
          <div class="completion-rate">{{ goalData.progressPercent }}%</div>
          <div class="completion-label">完成率</div>
        </div>
      </div>
      
      <div class="goal-metrics">
        <div class="metrics-section time-section">
          <div class="time-remaining">
            <div class="time-value">{{ goalData.remainingDays }}</div>
            <div class="time-label">剩余天数</div>
          </div>
          
          <div class="time-progress-container">
            <div class="time-progress-text">
              <span>时间进度</span>
              <span>{{ calculateTimeProgress() }}%</span>
            </div>
            <el-progress 
              :percentage="calculateTimeProgress()" 
              :stroke-width="8" 
              :show-text="false"
              :color="getTimeProgressColor()"
            ></el-progress>
          </div>
        </div>
        
        <div class="metrics-section values-section">
          <div class="metric-item">
            <div class="metric-label">当前销售额</div>
            <div class="metric-value">{{ formatCurrency(goalData.currentValue) }}</div>
          </div>
          
          <div class="metric-item">
            <div class="metric-label">目标销售额</div>
            <div class="metric-value target">{{ formatCurrency(goalData.targetValue) }}</div>
          </div>
          
          <div class="metric-gap">
            <div class="gap-value" :class="{'gap-positive': goalDifference() >= 0, 'gap-negative': goalDifference() < 0}">
              {{ goalDifference() >= 0 ? '超前' : '落后' }} {{ formatCurrency(Math.abs(goalDifference())) }}
            </div>
            <div class="gap-label">与时间进度{{ progressDifference() >= 0 ? '超前' : '落后' }} {{ Math.abs(progressDifference()).toFixed(1) }}%</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, onMounted, onUnmounted, watch, PropType, nextTick } from 'vue'
import * as echarts from 'echarts/core'
import { GaugeChart } from 'echarts/charts'
import { TitleComponent, TooltipComponent } from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'

echarts.use([TitleComponent, TooltipComponent, GaugeChart, CanvasRenderer])

interface GoalData {
  currentValue: number
  targetValue: number
  progressPercent: number
  remainingDays: number
  totalDays: number
}

export default defineComponent({
  name: 'SalesGoalCard',
  props: {
    goalData: {
      type: Object as PropType<GoalData>,
      required: true
    },
    periodType: {
      type: String as PropType<'weekly' | 'monthly' | 'quarterly' | 'yearly'>,
      default: 'monthly'
    }
  },
  emits: ['period-change'],
  setup(props, { emit }) {
    const selectedPeriod = ref(props.periodType)
    const gaugeRef = ref<HTMLElement | null>(null)
    let gaugeChart: echarts.ECharts | null = null
    
    // 处理周期更改
    const handlePeriodChange = (period: string | number | boolean | undefined) => {
      if (typeof period === 'string') {
        emit('period-change', period)
      }
    }
    
    // 计算目标差值
    const goalDifference = () => {
      const currentGoalRatio = props.goalData.currentValue / props.goalData.targetValue
      const timeRatio = calculateTimeProgress() / 100
      
      return props.goalData.targetValue * (currentGoalRatio - timeRatio)
    }
    
    // 计算进度差异
    const progressDifference = () => {
      const timeProgress = calculateTimeProgress()
      return props.goalData.progressPercent - timeProgress
    }
    
    // 计算时间进度百分比
    const calculateTimeProgress = () => {
      if (props.goalData.totalDays === 0) return 0
      
      const elapsedDays = props.goalData.totalDays - props.goalData.remainingDays
      return Math.min(100, Math.max(0, Math.round(elapsedDays / props.goalData.totalDays * 100)))
    }
    
    // 获取时间进度条颜色
    const getTimeProgressColor = () => {
      const progress = calculateTimeProgress()
      
      if (progress < 30) return '#409EFF'  // 蓝色
      if (progress < 70) return '#67C23A'  // 绿色
      if (progress < 90) return '#E6A23C'  // 黄色
      return '#F56C6C'  // 红色
    }
    
    // 格式化货币
    const formatCurrency = (value: number) => {
      if (value >= 1000000) {
        return (value / 1000000).toFixed(2) + '百万'
      } else if (value >= 10000) {
        return (value / 10000).toFixed(2) + '万'
      }
      
      return new Intl.NumberFormat('zh-CN', {
        minimumFractionDigits: 0,
        maximumFractionDigits: 0
      }).format(value)
    }
    
    // 初始化仪表图
    const initGaugeChart = () => {
      if (!gaugeRef.value) return
      
      gaugeChart = echarts.init(gaugeRef.value)
      updateGaugeChart()
      
      window.addEventListener('resize', handleResize)
    }
    
    // 更新仪表图数据
    const updateGaugeChart = () => {
      if (!gaugeChart) return
      
      const progressPercent = props.goalData.progressPercent
      
      // 仪表图配置选项
      const option = {
        series: [
          {
            type: 'gauge',
            startAngle: 180,
            endAngle: 0,
            center: ['50%', '60%'],
            radius: '100%',
            min: 0,
            max: 100,
            splitNumber: 10,
            axisLine: {
              lineStyle: {
                width: 14,
                color: [
                  [0.3, '#F56C6C'],
                  [0.7, '#E6A23C'],
                  [1, '#67C23A']
                ]
              }
            },
            pointer: {
              icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
              length: '12%',
              width: 10,
              offsetCenter: [0, '-60%'],
              itemStyle: {
                color: 'auto'
              }
            },
            axisTick: {
              length: 6,
              distance: -14,
              lineStyle: {
                color: '#fff',
                width: 2
              }
            },
            splitLine: {
              length: 10,
              distance: -14,
              lineStyle: {
                color: '#fff',
                width: 2
              }
            },
            axisLabel: {
              distance: -40,
              color: '#999',
              fontSize: 10
            },
            detail: {
              show: false
            },
            data: [
              {
                value: progressPercent
              }
            ],
            animation: true,
            animationDuration: 1000
          }
        ]
      }
      
      gaugeChart.setOption(option)
    }
    
    // 响应式调整图表大小
    const handleResize = () => {
      gaugeChart?.resize()
    }
    
    // 监听数据变化，更新图表
    watch(
      () => props.goalData,
      () => nextTick(updateGaugeChart),
      { deep: true }
    )
    
    // 组件挂载时初始化图表
    onMounted(() => {
      nextTick(initGaugeChart)
    })
    
    // 组件卸载时销毁图表实例
    onUnmounted(() => {
      if (gaugeChart) {
        gaugeChart.dispose()
        gaugeChart = null
      }
      window.removeEventListener('resize', handleResize)
    })
    
    return {
      selectedPeriod,
      gaugeRef,
      handlePeriodChange,
      formatCurrency,
      calculateTimeProgress,
      getTimeProgressColor,
      goalDifference,
      progressDifference
    }
  }
})
</script>

<style scoped lang="scss">
.sales-goal-card {
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  padding: 20px;
  height: 100%;
  display: flex;
  flex-direction: column;
  
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    
    .card-title {
      margin: 0;
      font-size: 16px;
      font-weight: 600;
      color: #303133;
    }
  }
  
  .goal-content {
    flex: 1;
    display: flex;
    gap: 20px;
    
    .goal-gauge {
      flex: 1;
      position: relative;
      
      .gauge-container {
        height: 180px;
        width: 100%;
      }
      
      .gauge-center {
        position: absolute;
        top: 60%;
        left: 50%;
        transform: translate(-50%, -50%);
        text-align: center;
        
        .completion-rate {
          font-size: 24px;
          font-weight: 700;
          color: #303133;
        }
        
        .completion-label {
          font-size: 12px;
          color: #909399;
          margin-top: 2px;
        }
      }
    }
    
    .goal-metrics {
      flex: 1;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      gap: 15px;
      
      .metrics-section {
        background-color: #f8f9fa;
        border-radius: 8px;
        padding: 15px;
      }
      
      .time-section {
        display: flex;
        flex-direction: column;
        gap: 15px;
        
        .time-remaining {
          display: flex;
          align-items: center;
          gap: 10px;
          
          .time-value {
            font-size: 28px;
            font-weight: 700;
            color: #409EFF;
            line-height: 1;
          }
          
          .time-label {
            font-size: 13px;
            color: #606266;
            line-height: 1;
          }
        }
        
        .time-progress-container {
          .time-progress-text {
            display: flex;
            justify-content: space-between;
            margin-bottom: 5px;
            font-size: 12px;
            color: #606266;
          }
        }
      }
      
      .values-section {
        display: flex;
        flex-direction: column;
        gap: 10px;
        
        .metric-item {
          display: flex;
          justify-content: space-between;
          align-items: center;
          
          .metric-label {
            font-size: 13px;
            color: #606266;
          }
          
          .metric-value {
            font-size: 14px;
            font-weight: 600;
            color: #303133;
            
            &.target {
              color: #67C23A;
            }
          }
        }
        
        .metric-gap {
          margin-top: 5px;
          
          .gap-value {
            text-align: center;
            font-size: 15px;
            font-weight: 600;
            margin-bottom: 3px;
            
            &.gap-positive {
              color: #67C23A;
            }
            
            &.gap-negative {
              color: #F56C6C;
            }
          }
          
          .gap-label {
            text-align: center;
            font-size: 12px;
            color: #909399;
          }
        }
      }
    }
  }
}

@media (max-width: 768px) {
  .sales-goal-card {
    .goal-content {
      flex-direction: column;
      
      .goal-gauge {
        .gauge-container {
          height: 150px;
        }
      }
    }
  }
}
</style> 